package com.managertrade.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.managertrade.dto.*;
import org.apache.commons.compress.utils.Lists;
import org.springframework.util.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

public class OkxPerpClient {

    private static final String BASE_URL = "https://www.okx.com";
    private static final String API_KEY = "d21adddf-ee71-4a48-b215-bec9c2d20d2a";
    private static final String API_SECRET = "DEDA389015CA14726EB1AB1382516EB9";
    private static final String PASSPHRASE = "Tftf5608.";


    public static OkxPlaceOrderResultDTO placeOrderFutureOkex(String instId,String side,Map<String, InstrumentResponseDTO.Instrument> sz,BigDecimal marginU) throws Exception {
        List<Integer> leverages = Lists.newArrayList();
        leverages.add(10);
        leverages.add(5);
        safeSetLeverage(instId,leverages);
        Map<String, Integer> maxMargin = getMaxMargin(instId);
        Map<String, String> klines = getKlines(instId);
        String  price = klines.get(instId);
        InstrumentResponseDTO.Instrument instrument = sz.get(instId);
        BigDecimal maxLeverage = new BigDecimal(25); // 或者从 instrument 中获取
        if(maxLeverage.compareTo(BigDecimal.valueOf(maxMargin.get(instId)))>0){
            maxLeverage = BigDecimal.valueOf(maxMargin.get(instId));
        }
        BigDecimal orderSz = calcSz(marginU, new BigDecimal(price), maxLeverage, instrument); // 0.8 USDT 保证金
        OkxPlaceOrderRequestDTO okxPlaceOrderRequestDTO = new OkxPlaceOrderRequestDTO();
        okxPlaceOrderRequestDTO.setInstId(instId);
        okxPlaceOrderRequestDTO.setTdMode("isolated");
        okxPlaceOrderRequestDTO.setSz(orderSz.toPlainString());
        okxPlaceOrderRequestDTO.setSide(side);
        okxPlaceOrderRequestDTO.setOrdType("market");
        okxPlaceOrderRequestDTO.setReduceOnly(false);
        okxPlaceOrderRequestDTO.setPx(null);
        //持仓模式（单仓模式）
        okxPlaceOrderRequestDTO.setPosSide(null);
        //保证金币种
        okxPlaceOrderRequestDTO.setCcy("USDT");
        // 下单
        OkxOrderResponseDTO okxOrderResponseDTO = placeOrder(okxPlaceOrderRequestDTO);
        // 封装返回
        OkxPlaceOrderResultDTO resultDTO = new OkxPlaceOrderResultDTO();
        resultDTO.setRequest(okxPlaceOrderRequestDTO);
        resultDTO.setResponse(okxOrderResponseDTO);
        return resultDTO;
    }


    /**
     * 获取当前账户持仓
     */
    public static OkxPositionResponseDTO getAccountPositions() throws Exception {
        String url = "https://www.okx.com/api/v5/account/positions?instType=SWAP";
        String method = "GET";

        // requestPath 必须带上 query 参数
        String requestPath = "/api/v5/account/positions?instType=SWAP";

        String body = "";  // GET 请求没有 body
        String timestamp = Instant.now().toString();

        // 签名：timestamp + method + requestPath + body
        String sign = generateSign(timestamp, method, requestPath, body, API_SECRET);

        // 请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");

        String rersult = OkxProxyHttpClient.getUserHead(url, headers);
        ObjectMapper mapper = new ObjectMapper();
        OkxPositionResponseDTO resp = mapper.readValue(rersult, OkxPositionResponseDTO.class);
         return resp;
    }

    public static BigDecimal getOrderPnl(String instId, String ordId) throws Exception {
        // 构建请求参数
        String url = "https://www.okx.com/api/v5/trade/fills?instId=" + instId+"&ordId=" + ordId;
        String method = "GET";
        String requestPath = "/api/v5/trade/fills?instId=" + instId+"&ordId=" + ordId;;
        String body = "";  // GET 请求没有 body
        String timestamp = Instant.now().toString();

        // 签名：timestamp + method + requestPath + body
        String sign = generateSign(timestamp, method, requestPath, body, API_SECRET);

        // 请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");

        // 调用私有接口，需要签名
        String result = OkxProxyHttpClient.getUserHead(url, headers); // 你自己封装的带签名 GET 方法

        ObjectMapper objectMapper = new ObjectMapper();
        OkxFillResponseDTO response = objectMapper.readValue(result, OkxFillResponseDTO.class);

        if (!"0".equals(response.getCode()) || response.getData() == null) {
            return BigDecimal.ZERO;
        }

        // 累加所有成交的 pnl
        return response.getData().stream()
                .map(f -> {
                    try {
                        return new BigDecimal(f.getPnl());
                    } catch (Exception e) {
                        return BigDecimal.ZERO;
                    }
                })
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    // 下单
    public static OkxOrderResponseDTO placeOrder(OkxPlaceOrderRequestDTO dto) throws Exception {
        String url = "https://www.okx.com/api/v5/trade/order";
        // 使用 ISO8601 UTC 时间戳
        String timestamp = Instant.now().toString();
        // 请求体
        ObjectMapper objectMapper = new ObjectMapper();
        String bodyJson = objectMapper.writeValueAsString(dto);

        // 签名
        String method = "POST";
        String requestPath = "/api/v5/trade/order";
        String sign = generateSign(timestamp, method, requestPath, bodyJson, API_SECRET);

        // 请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");
        headers.put("Accept", "application/json");
        headers.put("User-Agent", "Mozilla/5.0");

        String result = OkxProxyHttpClient.postJson(url, bodyJson, headers);
        ObjectMapper mapper = new ObjectMapper();
        OkxOrderResponseDTO resultDto = mapper.readValue(result, OkxOrderResponseDTO.class);
        return resultDto;
    }
    public static void safeSetLeverage(String instId, List<Integer> leverages) throws Exception {
        Exception lastException = null;
        for (Integer lev : leverages) {
            try {
                // 尝试设置杠杆
                Boolean aBoolean = setLever(String.valueOf(lev), instId);
                if(aBoolean){
                    System.out.println("杠杆设置成功: " + lev + "倍");
                    return;
                }
            } catch (Exception e) {
                System.err.println("设置杠杆失败: " + lev + "倍, 错误信息: " + e.getMessage());
                lastException = e;
            }
        }
        // 如果所有倍数都失败，抛出最后一次异常
        throw new RuntimeException("所有候选杠杆设置均失败，请检查账户保证金或合约限制", lastException);
    }
    public static Boolean setLever(String lever,String instId) throws Exception {
        // 构造请求体
        Map<String, Object> dto = new HashMap<>();
        dto.put("instId", instId); // 合约ID
        dto.put("mgnMode", "isolated");       // 全仓/逐仓
        dto.put("lever", lever);            // 杠杆倍数
        //dto.put("posSide", "long");        // 持仓方向，可选 long/short
        // URL 和请求方法
        String url = "https://www.okx.com/api/v5/account/set-leverage";
        String method = "POST";
        String requestPath = "/api/v5/account/set-leverage";

        // ISO8601 UTC 时间戳
        String timestamp = Instant.now().toString();

        // 请求体 JSON
        ObjectMapper objectMapper = new ObjectMapper();
        String bodyJson = objectMapper.writeValueAsString(dto);

        // 生成签名
        String sign = generateSign(timestamp, method, requestPath, bodyJson, API_SECRET);

        // 请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");
        headers.put("Accept", "application/json");
        headers.put("User-Agent", "Mozilla/5.0");

        String result = OkxProxyHttpClient.postJson(url, bodyJson, headers);
        System.out.println("下单响应结果: " + result);
        ObjectMapper mapper = new ObjectMapper();
        SetLeverageResponseDTO resultDto = mapper.readValue(result, SetLeverageResponseDTO.class);
        if(!resultDto.getCode().equals("0")){
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }
    // HMAC-SHA256 + Base64
    private static String generateSign(String timestamp, String method, String requestPath, String body, String secretKey) throws Exception {
        String preSign = timestamp + method.toUpperCase() + requestPath + body;
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        sha256_HMAC.init(new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] hash = sha256_HMAC.doFinal(preSign.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(hash);
    }
    // 获取 OKX 系统时间
    public static String getServerTime() throws Exception {
        URL url = new URL(BASE_URL + "/api/v5/public/time");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(10000);
        conn.setReadTimeout(10000);

        InputStream is = conn.getResponseCode() < 400 ? conn.getInputStream() : conn.getErrorStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
        StringBuilder resp = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            resp.append(line);
        }
        reader.close();

        JSONObject json = JSONObject.parseObject(resp.toString());
        JSONArray data = json.getJSONArray("data");
        return data.getJSONObject(0).getString("iso");
    }


    // 封装下单逻辑
    public static OkxOrderResponseDTO placeCloseOrder(String instId, String tdMode, String posSide, String side, String sz) throws Exception {
        String url = "https://www.okx.com/api/v5/trade/order";
        String method = "POST";
        String requestPath = "/api/v5/trade/order";

        Map<String, Object> body = new HashMap<>();
        body.put("instId", instId);
        body.put("tdMode", tdMode);
        body.put("posSide", posSide);
        body.put("side", side);
        body.put("ordType", "market");
        body.put("reduceOnly", true);
        body.put("sz", sz);

        ObjectMapper objectMapper = new ObjectMapper();
        String bodyJson = objectMapper.writeValueAsString(body);

        String timestamp = Instant.now().toString();
        String sign = generateSign(timestamp, method, requestPath, bodyJson, API_SECRET);

        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");
        headers.put("Accept", "application/json");
        headers.put("User-Agent", "Mozilla/5.0");

        String resp = OkxProxyHttpClient.postJson(url, bodyJson, headers);
        ObjectMapper mapper = new ObjectMapper();
        OkxOrderResponseDTO result = mapper.readValue(resp, OkxOrderResponseDTO.class);
        return result;
    }

    /**
     * 获取当前我的跟单详细信息
     */
    public static OkxResponseDTO<CopyTradingSubPositionDTO> getCurrentSubpositions(String instId) throws Exception {
        String url = "https://www.okx.com/";
        String method = "GET";

        // requestPath 必须带上 query 参数
        String requestPath = "/api/v5/copytrading/current-subpositions";
        String query = "";
        if(!StringUtils.isEmpty(instId)){
            query = "?instId=" + instId; // 可选参数：instType、uniqueCode 等
        }
        url = url + requestPath + query;

        String body = "";  // GET 请求没有 body
        String timestamp = Instant.now().toString();

        // 签名：timestamp + method + requestPath + body
        String sign = generateSign(timestamp, method, requestPath, body, API_SECRET);

        // 请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");

        String rersult = OkxProxyHttpClient.getUserHead(url, headers);
        OkxResponseDTO<CopyTradingSubPositionDTO> responseObj =
                new ObjectMapper().readValue(rersult,
                        new com.fasterxml.jackson.core.type.TypeReference<OkxResponseDTO<CopyTradingSubPositionDTO>>() {});
        return responseObj;
    }

    /**
     * 获取跟单交易员当前仓位信息
     * @return
     * @throws Exception
     */
    public static LeadTraderCurrentPositionsResponseDTO getCurrentLeadPositions(String uniqueCode) throws Exception {
        String url = "https://www.okx.com";
        String urlPath = "/api/v5/copytrading/public-current-subpositions";
        String query = "?uniqueCode=" + uniqueCode + "&instType=SWAP"; // 指定合约类型
        String timestamp = Instant.now().toString();
        String method = "GET";
        String fullPathForSign = urlPath + "?" + query;
        String sign = generateSign(timestamp, method, fullPathForSign, "", API_SECRET);

        // 请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");

        String rersult = OkxProxyHttpClient.getUserHead(url+urlPath+query, headers);
        ObjectMapper objectMapper = new ObjectMapper();
        LeadTraderCurrentPositionsResponseDTO responseVO =
                objectMapper.readValue(rersult, LeadTraderCurrentPositionsResponseDTO.class);
        return responseVO;
    }

    /**
     * 获取合约标的的最低
     */

    public static Map<String, InstrumentResponseDTO.Instrument> getInstruments() throws Exception {

        String url = "https://www.okx.com";
        String urlPath = "/api/v5/public/instruments";
        // 必须指定 instType，instId 可选
        String query = "instType=SWAP&instId";
        String result = OkxProxyHttpClient.getUserHead(url + urlPath + "?" + query, new HashMap<>());
        ObjectMapper objectMapper = new ObjectMapper();
        InstrumentResponseDTO instrumentResponseDTO = objectMapper.readValue(result, InstrumentResponseDTO.class);
        Map<String, InstrumentResponseDTO.Instrument> collect = instrumentResponseDTO.getData().stream()
                .filter(inst -> inst.getInstId() != null && !inst.getInstId().isEmpty())
                .collect(Collectors.toMap(
                        InstrumentResponseDTO.Instrument::getInstId,
                        inst -> inst)
                );
        return collect;
    }
    /**
     * 获取合约的最大倍数
     * @param instId
     * @return
     * @throws Exception
     */
    public static Map<String, Integer> getMaxMargin(String instId) throws Exception {


        String url = "https://www.okx.com/api/v5/account/leverage-info?"+"instId=" + instId + "&mgnMode=isolated";
        String method = "GET";
        // requestPath 必须带上 query 参数
        String requestPath = "/api/v5/account/leverage-info?"+"instId=" + instId + "&mgnMode=isolated";
        String body = "";  // GET 请求没有 body
        String timestamp = Instant.now().toString();
        // 签名：timestamp + method + requestPath + body
        String sign = generateSign(timestamp, method, requestPath, body, API_SECRET);
        // 请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");
        String result = OkxProxyHttpClient.getUserHead(url, headers);
        Map<String, Integer> collect =  new HashMap<>();
        ObjectMapper objectMapper = new ObjectMapper();
        LeveragesResponseDTO instrumentResponseDTO = objectMapper.readValue(result, LeveragesResponseDTO.class);
        if(instrumentResponseDTO!=null  && !instrumentResponseDTO.getData().isEmpty()){
          collect = instrumentResponseDTO.getData().stream().collect(Collectors.toMap(LeveragesResponseDTO.LeverageData::getInstId,
                    data -> Integer.parseInt(data.getLever())));
        }
        return collect;
    }

    public static Map<String,String> getKlines(String instId) throws Exception {
        String url = "https://www.okx.com/api/v5/market/candles";
        String query = String.format("instId=%s&bar=%s&limit=%s", instId, "1H", "1");
        String fullUrl = url + "?" + query;
        String result = OkxProxyHttpClient.getUserHead(fullUrl, new HashMap<>());
        ObjectMapper mapper = new ObjectMapper();

        JsonNode root = mapper.readTree(result);
        KlineResponseDTO response = new KlineResponseDTO();
        response.setCode(root.get("code").asText());
        response.setMsg(root.get("msg").asText());
        Map<String,String> map = new HashMap<>();
        List<KlineResponseDTO.KlineData> klines = new ArrayList<>();
        if ("0".equals(response.getCode())) {
            for (JsonNode node : root.get("data")) {
                // node 是一个 ArrayNode
                KlineResponseDTO.KlineData k = new KlineResponseDTO.KlineData();
                k.setTimestamp(node.get(0).asLong());
                k.setOpen(new BigDecimal(node.get(1).asText()));
                k.setHigh(new BigDecimal(node.get(2).asText()));
                k.setLow(new BigDecimal(node.get(3).asText()));
                k.setClose(new BigDecimal(node.get(4).asText()));
                k.setVolume(new BigDecimal(node.get(5).asText()));
                klines.add(k);
                map.put(instId,String.valueOf(k.getClose()));
                break;
            }
        }
        return map;
    }




    public static BigDecimal calcSz(BigDecimal marginU, BigDecimal price, BigDecimal maxLeverage, InstrumentResponseDTO.Instrument instrument) {
        BigDecimal ctVal  = new BigDecimal(instrument.getCtVal());   // 合约面值
        BigDecimal ctMult = new BigDecimal(instrument.getCtMult());  // 合约乘数
        BigDecimal lotSz  = new BigDecimal(instrument.getLotSz());   // 下单精度
        BigDecimal minSz  = new BigDecimal(instrument.getMinSz());   // 最小下单数量

        // 原始张数 = 保证金 * 杠杆 / (价格 * 合约面值 * 合约乘数)
        BigDecimal rawSz = marginU.multiply(maxLeverage).divide(price.multiply(ctVal).multiply(ctMult), 12, RoundingMode.HALF_UP);

        // 向上取整到 lotSz 的整数倍
        BigDecimal sz = rawSz.divide(lotSz, 0, RoundingMode.UP).multiply(lotSz);

        // 至少 minSz
        if (sz.compareTo(minSz) < 0) {
            sz = minSz;
        }

        return sz.stripTrailingZeros();
    }


    /**
     * 获取交易员历史带单
     * @param args
     * @throws Exception
     */
    public static List<CopyTradingSubPositionsHistoryResponse.SubPosition> getTraderHistory(String uniqueCode,String subPosId) throws Exception {
        String url = "https://www.okx.com/api/v5/copytrading/public-subpositions-history?"+"instType=" + "SWAP" + "&uniqueCode="+uniqueCode;
        String method = "GET";
        // requestPath 必须带上 query 参数
        String requestPath = "/api/v5/copytrading/public-subpositions-history?"+"instType=" + "SWAP" + "&uniqueCode="+uniqueCode;
        if(!StringUtils.isEmpty(subPosId)){
            url = url+"&subPosId="+subPosId;
            requestPath = requestPath+"&subPosId="+subPosId;
        }
        String body = "";  // GET 请求没有 body
        String timestamp = Instant.now().toString();
        // 签名：timestamp + method + requestPath + body
        String sign = generateSign(timestamp, method, requestPath, body, API_SECRET);
        // 请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");
        String result = OkxProxyHttpClient.getUserHead(url, headers);
        Map<String, Integer> collect =  new HashMap<>();
        ObjectMapper objectMapper = new ObjectMapper();
        CopyTradingSubPositionsHistoryResponse instrumentResponseDTO = objectMapper.readValue(result, CopyTradingSubPositionsHistoryResponse.class);
        return instrumentResponseDTO.getData();
    }



    /**
     * 判断 subPosId 是否已经平仓
     * @param traderId 交易员唯一ID
     * @param subPosId 子仓位ID
     * @return true 已平仓，false 还在持仓
     * @throws Exception
     */
    public static boolean isSubPositionClosed(String traderId, String subPosId) throws Exception {
        // 去历史仓位里查一下
        List<CopyTradingSubPositionsHistoryResponse.SubPosition> historyPositions =
                OkxPerpClient.getTraderHistory(traderId, "");
        if (historyPositions != null) {
            boolean inHistory = historyPositions.stream()
                    .anyMatch(p -> subPosId.equals(p.getSubPosId()));
            if (inHistory) {
                return true; // 出现在历史仓位里，说明已平仓
            }
        }

        // 不在当前仓位，也不在历史仓位 → 可能 subPosId 错误，或者数据还没同步
        return true;
    }
    /**
     * 获取历史账单
     * type 的常见值（部分）
     *
     * 1：转账
     *
     * 2：交易
     *
     * 3：交割/行权
     *
     * 4：自动换币
     *
     * 5：强制减仓
     *
     * 6：资金费用
     *
     * 7：自动减仓（ADL）
     *
     * 8：平仓手续费（你现在用的）
     *
     * 9：交割费用
     */
    public static OkxBillsResponseDTO getOrderBills(String instId, String ordId) throws Exception {
        String url = "https://www.okx.com/api/v5/account/bills?instId=" + instId + "&ordId=" + ordId + "&type=2&subType=2";
        String method = "GET";
        String requestPath = "/api/v5/account/bills?instId=" + instId + "&ordId=" + ordId + "&type=2&subType=2";

        String timestamp = Instant.now().toString();
        String sign = generateSign(timestamp, method, requestPath, "", API_SECRET); // GET请求无body

        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");

        String resp = OkxProxyHttpClient.getUserHead(url, headers);
        ObjectMapper mapper = new ObjectMapper();
        OkxBillsResponseDTO okxBillsResponseDTO = mapper.readValue(resp, OkxBillsResponseDTO.class);
        return okxBillsResponseDTO;
    }

    /**
     * 获取某个订单的亏盈
     * @param args
     * @throws Exception
     */
    public static OkxOrderHistoryResponseDTO.OrderData getOrdersHistory(String instId, String ordId) throws Exception {
        String url = "https://www.okx.com/api/v5/trade/orders-history?instType=SWAP&instId="
                + instId + "&ordId=" + ordId;
        String method = "GET";
        String requestPath = "/api/v5/trade/orders-history?instType=SWAP&instId="
                + instId + "&ordId=" + ordId;

        String timestamp = Instant.now().toString();
        String sign = generateSign(timestamp, method, requestPath, "", API_SECRET); // GET请求无body

        Map<String, String> headers = new HashMap<>();
        headers.put("OK-ACCESS-KEY", API_KEY);
        headers.put("OK-ACCESS-SIGN", sign);
        headers.put("OK-ACCESS-TIMESTAMP", timestamp);
        headers.put("OK-ACCESS-PASSPHRASE", PASSPHRASE);
        headers.put("Content-Type", "application/json");

        String resp = OkxProxyHttpClient.getUserHead(url, headers);
        ObjectMapper mapper = new ObjectMapper();
        OkxOrderHistoryResponseDTO okxBillsResponseDTO = mapper.readValue(resp, OkxOrderHistoryResponseDTO.class);
        List<OkxOrderHistoryResponseDTO.OrderData> collect = okxBillsResponseDTO.getData().stream().filter(k ->
                k.getInstId().equals(instId) && ordId.equals(k.getOrdId())).collect(Collectors.toList());
        if(collect.size()>0){
            return collect.get(0);
        }
        return null;
    }
    public static void main(String[] args) throws Exception {
        getOrderPnl("YGG-USDT-SWAP","2857299652262436864");
    }
}


